package com.xiaoyu.base.utils.upload

import `in`.srain.cube.request.RequestData
import android.graphics.BitmapFactory
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.utils.upload.UploadMediaType.UploadMediaTypeDef
import `in`.srain.cube.util.FilenameUtil
import `in`.srain.cube.util.general.GeneralUtil
import `in`.srain.cube.util.internal.AppCallback
import com.xiaoyu.base.utils.FileUtil
import com.xiaoyu.base.utils.VideoUtil
import java.util.*
import java.util.concurrent.Callable

class UploadParam constructor(val filePath: String, val category: Category, val mediaType: String, val chatId: String = "", @UploadImageOriginalType.OriginalTypeDef val original: Int = UploadImageOriginalType.COMPRESSED) {

    fun upload(listener: UploadListener) {
        QiniuUploadManager.instance.upload(this, listener)
    }

    @Throws(Exception::class)
    fun uploadSync(): String {
        return QiniuUploadManager.instance.uploadSync(this)
    }

    fun addToRequestData(requestData: RequestData) {
        requestData.addQueryData("category", category.toString().toLowerCase(Locale.getDefault()))
        requestData.addQueryData("mediaType", mediaType)
        requestData.addQueryData("fileExtension", FilenameUtil.getExtension(filePath))
//        if (chatId != null) {
//            requestData.addQueryData("chat_id", chatId)
//        }
        addExtraToRequestData(requestData)
    }

    private fun addExtraToRequestData(requestData: RequestData) {
        val map = extraMap
        requestData.addQueryData(map)
    }

    private val extraMapForImage: Map<String, Any>
        get() {
            val options = BitmapFactory.Options()
            options.inJustDecodeBounds = true
            BitmapFactory.decodeFile(filePath, options)
            val size = FileUtil.getSizeForKB(filePath)
            val map: MutableMap<String, Any> = HashMap()
            map["w"] = options.outWidth
            map["h"] = options.outHeight
            map["size"] = size
            map["original"] = original
            return map
        }

    private val extraMapForAudio: Map<String, Any>
        get() {
            val map: MutableMap<String, Any> = HashMap()
            map["size"] = FileUtil.getSizeForKB(filePath)
            map["duration"] = VideoUtil.getDurationForSecond(AppContext.getContext(), filePath)
            return map
        }

    private val extraMapForVideo: Map<String, Any>
        get() {
            val map: MutableMap<String, Any> = HashMap()
            map["w"] = VideoUtil.getVideoWidth(AppContext.getContext(), filePath)
            map["h"] = VideoUtil.getVideoHeight(AppContext.getContext(), filePath)
            map["duration"] = VideoUtil.getDurationForSecond(AppContext.getContext(), filePath)
            map["size"] = FileUtil.getSizeForKB(filePath)
            return map
        }

    val extraMap: Map<String, Any>
        get() = when (mediaType) {
            UploadMediaType.IMAGE -> extraMapForImage
            UploadMediaType.VIDEO -> extraMapForVideo
            UploadMediaType.AUDIO -> extraMapForAudio
            else -> HashMap()
        }

    companion object {
        fun batchUpload(filePaths: Collection<String>, category: Category, @UploadMediaTypeDef mediaType: String, chatId: String = "", original: Int = UploadImageOriginalType.COMPRESSED, callback: AppCallback<List<String>>) {
            GeneralUtil.runFromBackgroundToMain(Callable { batchUploadSync(filePaths, category, mediaType, chatId, original) }, callback)
        }

        @Throws(Exception::class)
        fun batchUploadSync(filePaths: Collection<String>, category: Category, @UploadMediaTypeDef mediaType: String, chatId: String = "", original: Int): List<String> {
            val successRemoteUrls: MutableList<String> = ArrayList(filePaths.size)
            for (filePath in filePaths) {
                successRemoteUrls.add(UploadParam(filePath, category, mediaType, chatId, original).uploadSync())
            }
            return successRemoteUrls
        }
    }
}